這裡一樣新增好一個專案
預設建立的專案可以看到每個action 回傳型別都為一個IActionResult的interface,每一個回傳型別都會去實作該介面,有泛型意味。
ContentResult
可以用於指定一班文字回傳或者不同MIME型態的內文
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Net5AppDiffAction.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Net5AppDiffAction.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
public ContentResult GreetUser_GeneralStr()
{
return Content("Hello world from .net core mvc");
}
public ContentResult GreetUser_HTML()
{
return Content("<div><b>Hello world from .net core mvc</b></div>","text/html");
}
public ContentResult GreetUser_XML()
{
return Content("<div><b>Hello world from .net core mvc</b></div>", "text/xml");
}
}
}
效果
最常用的
ViewResult
回傳一個畫面
public ViewResult TodoList()
{
ViewBag.Message = "Todo List test";
return View();
}
效果
RedirectResult
網頁跳轉
有分兩種一般跳轉(status code:302)
跟永久跳轉(status code:301)
public RedirectResult GotoURL()
{
return Redirect("http://www.google.com"); //HTTP status code : 302
}
public RedirectResult GotoURLPermanently()
{
return RedirectPermanent("http://www.google.com"); //HTTP status code : 301
}
永久跳轉(status code:301)
通常若是要轉向到既有的檔案或自己站內的頁面
會建議用永久跳轉,有助於SEO成效。
如果資源已被永久刪除,將不再是先前的位置訪問。大部分Browser
都會緩存此響應並自動執行重定向,而無需再次請求原始資源。
一般跳轉(status code:302)
若想驗證回傳的status code可以下載Fiddler來自行測試
當Press Enter後即可從左側觀察的到status code回傳對應結果
RedirectToActionResult
跳轉到指定的action可傳相應的參數
public ViewResult TodoList(string Message = "Default Message for TodoList Test")
{
ViewBag.Message = Message;
return View();
}
public RedirectToActionResult GotoContactsAction()
{
return RedirectToAction("TodoList", new { Message = "I am coming from a different action..." });
}
效果
RedirectToRouteResult
藉由route的跳轉
在startup.cs中做一些route的設置修改
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5AppDiffAction
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "TodoListRoute",
pattern: "GotoAbout",
defaults: new { controller = "Home", action = "TodoList" });
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
這裡在HomeController.cs新增的這個action就是去透過指定route來做相應跳轉
public RedirectToRouteResult GotoAbout()
{
return (RedirectToRoute("TodoListRoute"));
}
這裡要注意各自對應參數要一致
效果
FileResult
用於文檔下載
public FileResult DownloadFile()
{
return File("/css/site.css","text/plain","download_newsite.css");
}
public FileResult ShowLogo()
{
return File("./Images/logo.png","images/png");
}
效果
FileContentResult
和FileResult不同點在於傳入參數要是binary型態
且結果不會下載而是直接呈現在網頁上
這裡準備預設./wwwroot/css/site.css和./Data/Products.xml兩種檔案
測試的action
public FileContentResult DownloadContent_css()
{
var testFile = System.IO.File.ReadAllBytes("./wwwroot/css/site.css");
return new FileContentResult(testFile,"text/plain");
}
public FileContentResult DownloadContent_xml()
{
var testFile = System.IO.File.ReadAllBytes("./Data/Products.xml");
return new FileContentResult(testFile, "text/xml");
}
效果
FileStreamResult
把文本內容透過stream形式寫入來做檔案下載
public FileStreamResult CreateFile()
{
var stream = new System.IO.MemoryStream(System.Text.Encoding.ASCII.GetBytes("Hello FileStreamResult"));
return new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("text/plain"))
{
FileDownloadName = "test.txt"
};
}
效果
VirtualFileResult 跟PhysicalFileResult
虛擬檔案路徑(相對路徑一定要存放wwwroot下的目錄)
跟
實際硬碟檔案路徑(要指定實際硬碟絕對路徑)
這裡我們注入IWebHostEnvironment 間接取得站台根目錄
測試程式
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Net5AppDiffAction.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Net5AppDiffAction.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IWebHostEnvironment _environment;
public HomeController(ILogger<HomeController> logger, IWebHostEnvironment enviroment)
{
_logger = logger;
_environment = enviroment;
}
public VirtualFileResult VirtualFileResultDemo()
{
return new VirtualFileResult("/css/site.css", "text/plain");
}
public PhysicalFileResult ShowProducts()
{
return new PhysicalFileResult(_environment.ContentRootPath + "/Data/Products.xml", "text/xml");
}
public PhysicalFileResult PhysicalFileResultDemo()
{
return new PhysicalFileResult(_environment.ContentRootPath + "/wwwroot/css/site.css", "text/plain");
}
}
}
效果
JsonResult
這裡準備創建好一個 model class Products
寫回傳Json result的 action
public JsonResult ShowNewProducts()
{
Products prod = new Products() { ProductCode = 101, ProductName = "Printer", Cost = 1500 };
return Json(prod);
}
藉由JsonResult序列化物件至JSON格式字串
運行效果
EmptyResult 和 NoContentResult
測試action
public EmptyResult EmptyResultDemo()
{
return new EmptyResult();
}
public NoContentResult NoContentResultDemo()
{
return NoContent();
}
各自差異在於
NoContentResult status code返回204
EmptyResult status code則是預設的200返回
使用時機
當你不想有任何response顯示在網頁上的時候
而同時也不想throw 出error直接給client端的時候
就會看你是傾向告知user你查詢結果為空(NoContentResult)
或者執行過程有錯(EmptyResult)
若想驗證回傳的status code可以下載Fiddler來自行測試
本文同步發表至個人部落格(分兩篇->因為鐵人賽規劃30天原先blog分兩篇章)
.NET Core第31天_Controller Action的各種不同回傳(ContentResult,ViewResult,RedirectResult,RedirectToActionResult,RedirectToRouteResult,FileResult)_part1
https://coolmandiary.blogspot.com/2021/08/net-core31controller.html
.NET Core第32天_Controller Action的各種不同回傳(FileContentResult,FileStreamResult,VirtualFileResult,PhysicalFileResult,JsonResult,EmptyResult,NoContentResult)_part2
https://coolmandiary.blogspot.com/2021/09/net-core32controller.html
雖然沒有成功連續不中斷每天發文
但仍然期許之後下次比賽可以挑戰成功
希望文章可以對於同樣新手學習有幫助
Ref:
Response.Redirect() vs Response.RedirectPermanent()
https://stackoverflow.com/questions/16537955/response-redirect-vs-response-redirectpermanent
Redirect() vs RedirectPermanent() in ASP.NET MVC
https://stackoverflow.com/questions/17517318/redirect-vs-redirectpermanent-in-asp-net-mvc
RedirectPermanent
https://www.c-sharpcorner.com/forums/redirectpermanent
FileResult In ASP.NET Core MVC
https://www.c-sharpcorner.com/article/fileresult-in-asp-net-core-mvc2/
認識 ASP․NET Core 檔案提供者與透過 Web API 下載實體檔案
https://blog.miniasp.com/post/2019/12/08/Understanding-File-Providers-in-ASP-NET-Core-and-Download-Physical-File
File Providers in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers?view=aspnetcore-3.1&WT.mc_id=DT-MVP-4015686
ASP.NET Core MVC returning file using FileResult
https://geeksarray.com/blog/aspnet-core-mvc-returning-file-using-fileresult